﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Com.JunCaiSoft.Common.AssistClass
{
    public static class ExpressionExt
    {
        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2,String name)
        {
            var newExp = Expression.Lambda<Func<T, bool>>(Expression.And(expr1.Body, expr2.Body), expr1.Parameters);
            var parameter = Expression.Parameter(typeof(T), name);
            var visitor = new ParameterReplacementVisitor(parameter);
            var parameterReplaceExp = (Expression<Func<T, bool>>)visitor.Visit(newExp);
            return parameterReplaceExp;
        }
        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2,String name)
        {
            var newExp = Expression.Lambda<Func<T, bool>>(Expression.Or(expr1.Body, expr2.Body), expr1.Parameters);
            var parameter = Expression.Parameter(typeof(T), name);
            var visitor = new ParameterReplacementVisitor(parameter);
            var parameterReplaceExp = (Expression<Func<T, bool>>)visitor.Visit(newExp);
            return parameterReplaceExp;
        }
        public static Expression<Func<T,bool>> True<T>()
        {

            return f => true;

        }

        public static Expression<Func<T,bool>> False<T>()

        {

            return f => false;

        }

        public static Expression<Func<T,bool>> Or<T>(this Expression<Func<T,bool>> expr1, Expression<Func<T,bool>> expr2)

        {

            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());

            return Expression.Lambda<Func<T, bool> > (Expression.Or(expr1.Body, invokedExpr), expr1.Parameters);

        }

        public static Expression<Func<T,bool>> And<T>(this Expression<Func<T,bool>> expr1, Expression<Func<T,bool>> expr2)
        {

            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());

            return Expression.Lambda<Func<T, bool>>(Expression.And(expr1.Body, invokedExpr), expr1.Parameters);

        }
    }
}
